import { _decorator } from 'cc';
import { Gomoku_Board, PieceType } from "./Gomoku_Board";
export enum AIDifficulty {
    Easy,
    Medium,
    Hard
}

export class Gomoku_AI {
    difficulty: AIDifficulty;
    constructor(difficulty: AIDifficulty) {
        this.difficulty = difficulty;
    }
    getMove(board: Gomoku_Board, myType: PieceType): [number, number] {
        switch (this.difficulty) {
            case AIDifficulty.Easy: return this.easyMove(board);
            case AIDifficulty.Medium: return this.mediumMove(board, myType);
            case AIDifficulty.Hard: return this.hardMove(board, myType);
        }
    }
    //    // === 简单难度：随机落子，偶尔会下在好位置 ===
    private easyMove(board: Gomoku_Board): [number, number] {
        const candidates: [number, number][] = [];
        const goodCandidates: [number, number][] = [];

        // 收集所有空位
        for (let i = 0; i < 15; i++) {
            for (let j = 0; j < 15; j++) {
                if (board.grid[i][j] === PieceType.None) {
                    candidates.push([i, j]);

                    // 检查是否是好位置（周围有棋子）
                    if (this.hasNearbyPieces(board, i, j)) {
                        goodCandidates.push([i, j]);
                    }
                }
            }
        }

        // 70%概率随机落子，30%概率选择好位置
        if (goodCandidates.length > 0 && Math.random() < 0.3) {
            return goodCandidates[Math.floor(Math.random() * goodCandidates.length)];
        }

        return candidates[Math.floor(Math.random() * candidates.length)];
    }
    //    // === 中等难度：贪心算法，会防守但不够全面 ===
    private mediumMove(board: Gomoku_Board, myType: PieceType): [number, number] {
        const enemyType = myType === PieceType.Black ? PieceType.White : PieceType.Black;
        let bestScore = -Infinity;
        let bestMove: [number, number] = [7, 7];

        for (let i = 0; i < 15; i++) {
            for (let j = 0; j < 15; j++) {
                if (board.grid[i][j] !== PieceType.None) continue;

                // 计算进攻分数
                let attackScore = this.evaluatePosition(board, i, j, myType);
                // 计算防守分数（权重较低）
                let defenseScore = this.evaluatePosition(board, i, j, enemyType) * 0.8;

                let totalScore = attackScore + defenseScore;

                // 添加一些随机性，避免过于机械
                totalScore += (Math.random() - 0.5) * 2;

                if (totalScore > bestScore) {
                    bestScore = totalScore;
                    bestMove = [i, j];
                }
            }
        }

        return bestMove;
    }
    //    // === 困难难度：完整的评分表算法，会全面考虑进攻和防守 ===
    private hardMove(board: Gomoku_Board, myType: PieceType): [number, number] {
        const enemyType = myType === PieceType.Black ? PieceType.White : PieceType.Black;
        const scoreTable = [0, 10, 100, 1000, 100000];
        let bestScore = -Infinity;
        let bestMove: [number, number] = [7, 7];

        for (let x = 0; x < 15; x++) {
            for (let y = 0; y < 15; y++) {
                if (board.grid[x][y] !== PieceType.None) continue;

                // 计算进攻分数
                let attackScore = this.getScore(board, x, y, myType, scoreTable);
                // 计算防守分数（权重相等）
                let defenseScore = this.getScore(board, x, y, enemyType, scoreTable);

                // 如果发现必胜或必败位置，优先选择
                if (attackScore >= 100000) {
                    return [x, y]; // 必胜位置
                }
                if (defenseScore >= 100000) {
                    return [x, y]; // 必败位置，必须防守
                }

                let totalScore = attackScore + defenseScore;

                if (totalScore > bestScore) {
                    bestScore = totalScore;
                    bestMove = [x, y];
                }
            }
        }

        return bestMove;
    }
    //    // === 检查位置周围是否有棋子（用于简单AI） ===
    private hasNearbyPieces(board: Gomoku_Board, x: number, y: number): boolean {
        for (let dx = -1; dx <= 1; dx++) {
            for (let dy = -1; dy <= 1; dy++) {
                if (dx === 0 && dy === 0) continue;

                let nx = x + dx;
                let ny = y + dy;

                if (nx >= 0 && nx < 15 && ny >= 0 && ny < 15) {
                    if (board.grid[nx][ny] !== PieceType.None) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    //    // === 评分表算法（困难AI使用） ===
    private getScore(board: Gomoku_Board, x: number, y: number, type: PieceType, table: number[]): number {
        const dirs = [[1, 0], [0, 1], [1, 1], [1, -1]];
        let score = 0;

        for (let [dx, dy] of dirs) {
            let count = 1;
            let blocked = 0; // 被阻挡的次数

            // 向两个方向检查
            for (let d = -1; d <= 1; d += 2) {
                let nx = x + dx * d;
                let ny = y + dy * d;
                let tempCount = 0;

                while (nx >= 0 && ny >= 0 && nx < 15 && ny < 15 && board.grid[nx][ny] === type) {
                    tempCount++;
                    nx += dx * d;
                    ny += dy * d;
                }

                count += tempCount;

                // 检查是否被阻挡
                if (nx < 0 || ny < 0 || nx >= 15 || ny >= 15 ||
                    (board.grid[nx][ny] !== PieceType.None && board.grid[nx][ny] !== type)) {
                    blocked++;
                }
            }

            // 根据被阻挡情况调整分数
            if (blocked === 2) {
                score += table[Math.min(count, 4)] * 0.1; // 完全被阻挡
            } else if (blocked === 1) {
                score += table[Math.min(count, 4)] * 0.5; // 部分被阻挡
            } else {
                score += table[Math.min(count, 4)]; // 完全开放
            }
        }

        return score;
    }
    //    // === 位置评估（中等AI使用） ===
    private evaluatePosition(board: Gomoku_Board, x: number, y: number, type: PieceType): number {
        const dirs = [[1, 0], [0, 1], [1, 1], [1, -1]];
        let score = 0;

        for (let [dx, dy] of dirs) {
            let count = 0;
            let space = 0; // 连续空间

            // 向两个方向检查
            for (let d = -1; d <= 1; d += 2) {
                let nx = x + dx * d;
                let ny = y + dy * d;
                let tempCount = 0;
                let tempSpace = 0;

                // 计算连续棋子数
                while (nx >= 0 && ny >= 0 && nx < 15 && ny < 15 && board.grid[nx][ny] === type) {
                    tempCount++;
                    nx += dx * d;
                    ny += dy * d;
                }

                // 计算连续空间数
                while (nx >= 0 && ny >= 0 && nx < 15 && ny < 15 && board.grid[nx][ny] === PieceType.None) {
                    tempSpace++;
                    nx += dx * d;
                    ny += dy * d;
                }

                count += tempCount;
                space += tempSpace;
            }

            // 根据连子数和空间计算分数
            if (count >= 4) {
                score += 10000; // 必胜
            } else if (count === 3 && space >= 2) {
                score += 1000; // 活三
            } else if (count === 3) {
                score += 100; // 眠三
            } else if (count === 2 && space >= 3) {
                score += 50; // 活二
            } else if (count === 2) {
                score += 10; // 眠二
            } else if (count === 1 && space >= 4) {
                score += 5; // 活一
            }
        }

        return score;
    }
}